package intersection;

import java.util.ArrayList;
import primitives.AbstractShape;
import primitives.World3D;
import ray.Ray;
import vector.Vector;

/**
 * Offer the result of the hit object for a ray in the world of all the objects
 * 
 * @author Yuting Wu
 * @author Kan Lin
 * @author Bing Dong
 * 
 */
public class GroupIntersection {
	// all the object exist in the space which are useful for the calculation
	private World3D world;
	// the distance from the hitpoint to ray's origin
	private double disHitpoint;
	// object which is hit
	private AbstractShape objHit;
	// vector of the hitpoint
	private Vector vHitpoint;
	// position of the hitpoint
	private Vector pHitpoint;

	/**
	 * 
	 * @param world
	 *            contain all the information about the object
	 */
	public GroupIntersection(World3D world) {
		super();
		this.world = world;

	}

	/**
	 * Calculate the hit object of a ray.With the help of the min method give
	 * the nearest object as the result for return
	 * 
	 * @param ray
	 * 
	 * @return the final hit object
	 */
	public boolean calMutiIntersection(final Ray ray) {

		ArrayList<AbstractShape> shape = world.getShape();

		disHitpoint = -1;
		boolean ifHit = true;

		for (AbstractShape obj : shape) {

			// judge whether the ray hit th object.
			if (obj.calMutiIntersection(ray, false)) {
				double disHP = obj.getDisHitPointIndex();
				if (disHP < 0) {
					System.out
							.println("There are something wrong in the distance calculation!");
				}
				// non hit before or distance is short
				if (disHitpoint == -1 || disHP < disHitpoint) {
					// do more calculation
					obj.runFurtherCalculation(ray);
					objHit = obj;
					disHitpoint = disHP;
					vHitpoint = obj.getVectorHitPointIndex();
					pHitpoint = obj.getPositionHitPointIndex();

				}
			}
		}

		// no object hit
		if (disHitpoint == -1) {
			ifHit = false;
		}
		return ifHit;

	}

	/**
	 * @return the objHit
	 */
	public AbstractShape getObjHit() {
		return objHit;
	}

	/**
	 * @return the disHitpoint
	 */
	public double getDisHitpoint() {
		return disHitpoint;
	}

	/**
	 * @return the vHitpoint
	 */
	public Vector getvHitpoint() {
		return vHitpoint;
	}

	/**
	 * @return the pHitpoint
	 */
	public Vector getpHitpoint() {
		return pHitpoint;
	}
}
